<?php

namespace App\Console;

use App\Events\BuyChange;
use App\Events\NoticeChange;
use App\Events\SellChange;
use App\Models\Buy;
use App\Models\Sell;
use App\Models\System;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;

class Kernel extends ConsoleKernel
{
  /**
   * The Artisan commands provided by your application.
   *
   * @var array
   */
  protected $commands = [
    //
  ];

  /**
   * Define the application's command schedule.
   *
   * @param  \Illuminate\Console\Scheduling\Schedule  $schedule
   * @return void
   */
  protected function schedule(Schedule $schedule)
  {
    // $schedule->command('inspire')->hourly();
    $schedule->call(function () {
      $this->buyFrozen();
      $this->buyTook();
      $this->sellLocking();
      // $this->sellUnlock();
      $this->buyCallback();
    })->everyMinute();
  }

  /**
   * Register the commands for the application.
   *
   * @return void
   */
  protected function commands()
  {
    $this->load(__DIR__ . '/Commands');

    require base_path('routes/console.php');
  }

  protected function buyFrozen()
  {
    $buys = Buy::where('state', 'frozen')->get();
    $callback_gaps = [1, 3, 10, 30, 60];
    $buys->each(function ($buy) use ($callback_gaps) {
      $limit = $buy->freeze_at->addMinutes($buy->agent->freeze_minutes);
      if (now()->greaterThan($limit)) {
        $buy->unfreeze();
      }
    });
  }

  protected function buyCallback()
  {
    $buys = Buy::where('state', 'unfreeze')
      ->where('callback_ok', 0)
      ->where('callback_num', '<', 5)
      ->whereNotNull('transaction_id')
      ->get();

    $gaps = [1, 3, 10, 30, 60];
    $buys->each(function ($buy) use ($gaps) {
      $gap = $gaps[$buy->callback_num];
      $limit = $buy->unfreeze_at->addMinutes($gap);
      if (now()->greaterThan($limit)) {
        $buy->callback();
      }
    });
  }

  protected function buyTook()
  {
    $buys = Buy::where('state', 'took')->get();
    $m = sys('took_lock_minutes');
    $buys->each(function ($buy) use ($m) {
      $limit = $buy->took_at->addMinutes($m);
      if (now()->greaterThan($limit)) {
        // \Log::debug('took expired: ' . $buy->id);
        event(new NoticeChange());
        event(new BuyChange($buy->seller_id, 'took-expired'));
      }
    });
  }

  protected function sellLocking()
  {
    $sells = Sell::where('state', 'locking')->get();
    $lock_minutes = (int) sys('sell_lock_minues');
    $sells->each(function ($sell) use ($lock_minutes) {
      $limit = $sell->updated_at->addMinutes($lock_minutes);
      if (now()->greaterThan($limit)) {
        \Log::debug('locking expired: ' . $sell->id);
        event(new NoticeChange());
        event(new SellChange($sell->id, 'locking-expired'));
      }
    });
  }

  // protected function sellUnlock()
  // {
  //   $sells = Sell::where('state', 'locking')->get();
  //   $sells->each->ifLockEnoughTime();
  // }
}
